home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-13 / mewin10s.zip / MSWEMACS.C < prev    next >
C/C++ Source or Header  |  1992-03-14  |  9KB  |  313 lines

  1. /* The routines in this file provide extra emacs functions available
  2.    under the Microsoft Windows environment on an IBM-PC or compatible
  3.    computer. The following functions are supplied: cutregion,
  4.    clipregion, insertclip and helpengine.
  5.  
  6.    Must be compiled with Borland C++ 2.0 or later version.
  7.  
  8.    It should not be compiled if the WINDOW_MSWIN symbol is not set */
  9.  
  10. #include    "estruct.h"
  11. #include    <stdio.h>
  12. #include    "eproto.h"
  13. #include    "edef.h"
  14. #include    "elang.h"
  15.  
  16. #include    "mswin.h"
  17.  
  18. static HANDLE   hClipData = NULL;   /* used by insertclip and
  19.                        ClipboardCleanup */
  20.  
  21. /* CopyToClipboard: internal function to copy region to clipboard */
  22. /* ===============                                                */
  23.  
  24. static BOOL pascal near CopyToClipboard (REGION *Region)
  25. {
  26.     long    Size = 0L;
  27.     HANDLE  hData;
  28.     char huge *Data;
  29.     BOOL    Result = TRUE;
  30.     register LINE *lp;
  31.     register int Offset;
  32.     register int lcnt;       /* used to reduce longop() overhead */
  33.     
  34.     /*-figure out the size of the clipboard data (end of lines have to
  35.        be turned into CR-LF) */
  36.     Size = Region->r_size;
  37.     if (curwp->w_dotp != curwp->w_markp[0]) {   /* multiple lines */
  38.         lp = Region->r_linep;
  39.         do {
  40.             ++Size;
  41.         lp = lforw(lp);
  42.     } while ((lp != curwp->w_dotp) && (lp != curwp->w_markp[0]));
  43.     }
  44.     if (Size == 0L) return TRUE;
  45.  
  46.     /*-copy the buffer data into a block of global memory */
  47.     if (hData = GlobalAlloc (GMEM_MOVEABLE, Size + 1)) {
  48.         if (!(Data = GlobalLock (hData))) goto NoClipboardMemory;
  49.     lp = Region->r_linep;
  50.     Offset = Region->r_offset;
  51.     lcnt = 0;
  52.     while (Size-- > 0) {
  53.         if (Offset != llength(lp)) {    /* middle of line */
  54.             *Data++ = lgetc(lp, Offset);
  55.             ++Offset;
  56.         }
  57.         else {                          /* end of line */
  58.             *Data++ = '\r';
  59.             *Data++ = '\n';
  60.             Size--;
  61.             lp = lforw(lp);
  62.             Offset = 0;
  63.             if (--lcnt < 0) {
  64.             longop (TRUE);
  65.             lcnt = 10;  /* reduce longop calls overhead */
  66.         }
  67.         }
  68.     }
  69.     *Data = '\0';
  70.     /*-pass the text to the clipboard */
  71.     GlobalUnlock (hData);
  72.     if (OpenClipboard (hFrameWnd)) {
  73.         if (EmptyClipboard ()) {
  74.             SetClipboardData (CF_TEXT, hData);
  75.         }
  76.         else Result = FALSE;
  77.         CloseClipboard ();
  78.     }
  79.     else Result = FALSE;
  80.     if (Result == FALSE) GlobalFree (hData);
  81.     }
  82.     else {
  83. NoClipboardMemory:
  84.     mlabort (TEXT94);   /* out of memory */
  85.         Result = FALSE;
  86.     }
  87.     return Result;
  88. } /* CopyToClipboard */
  89.  
  90. /* cutregion:   move the current region to the clipboard */
  91. /* =========                                             */
  92.  
  93. PASCAL cutregion (int f, int n)
  94. {
  95.     REGION  Region;
  96.     int     Result;
  97.  
  98.     /*-don't allow command if read-only mode */
  99.     if (curbp->b_mode & MDVIEW) return rdonly();
  100.  
  101.     if ((Result = getregion (&Region)) != TRUE) return Result;
  102.  
  103.     if ((Result = CopyToClipboard (&Region)) != TRUE) return Result;
  104.     curwp->w_dotp = Region.r_linep;
  105.     curwp->w_doto = Region.r_offset;
  106.     return ldelete (Region.r_size, FALSE);
  107. } /* cutregion */
  108.  
  109. /* clipregion:  copy the current region into the clipboard */
  110. /* ==========                                              */
  111.  
  112. PASCAL clipregion (int f, int n)
  113. {
  114.     REGION  Region;
  115.     int     Result;
  116.     
  117.     if ((Result = getregion (&Region)) != TRUE) return Result;
  118.  
  119.     return CopyToClipboard (&Region);
  120. } /* clipregion */
  121.  
  122. /* insertclip:  insert the clipboard contents at dot */
  123. /* ==========                                        */
  124.  
  125. PASCAL insertclip (int f, int n)
  126. {
  127.     BOOL    Result = TRUE;
  128.     char    *Text, *TextHead;
  129.     short int curoff;
  130.     LINE    *curline;
  131.  
  132.     /*-don't allow command if read-only mode */
  133.     if (curbp->b_mode & MDVIEW) return rdonly();
  134.  
  135.     if (OpenClipboard (hFrameWnd)) {
  136.     if ((hClipData = GetClipboardData (CF_TEXT)) != NULL) {
  137.         /* Save the local pointers to hold global "." */
  138.         if (yankflag == SRBEGIN) {
  139.         /* Find the *previous* line, since the line we are on
  140.            may disappear due to re-allocation.  This works even
  141.            if we are on the first line of the file. */
  142.         curline = lback(curwp->w_dotp);
  143.         curoff = curwp->w_doto;
  144.         }
  145.         if ((TextHead = GlobalLock (hClipData)) != NULL) {
  146.         while (n--) {
  147.             Text = TextHead;
  148.             while (*Text != '\0') {
  149.             if (*Text == '\n') {
  150.                 if (lnewline () == FALSE) {
  151.                 Result = FALSE;
  152.                 goto bail_out;
  153.                 }
  154.             }
  155.             else {
  156.                 if (*Text != '\r') if (linsert (1, *Text) == FALSE) {
  157.                 Result = FALSE;
  158.                 goto bail_out;
  159.                 }
  160.             }
  161.             ++Text;
  162.             }
  163.         }
  164. bail_out:
  165.                 GlobalUnlock (hClipData);
  166.                 hClipData = NULL;   /* for ClipboardCleanup */
  167.                 /* If requested, set global "." back to the beginning of
  168.            the yanked text. */
  169.         if (yankflag == SRBEGIN) {
  170.             curwp->w_dotp = lforw(curline);
  171.             curwp->w_doto = curoff;
  172.         }
  173.         }
  174.     }
  175.     else Result = FALSE;
  176.     CloseClipboard ();
  177.     }
  178.     else Result = FALSE;
  179.     return Result;
  180. } /* insertclip */
  181.  
  182. /* ClipboardCleanup:    to be called if the user aborts during a longop */
  183. /* ================                                                     */
  184.  
  185. void far pascal ClipboardCleanup (void)
  186. {
  187.     if (hClipData) {
  188.         GlobalUnlock (hClipData);
  189.         CloseClipboard ();
  190.     }
  191. } /* ClipboardCleanup */
  192.  
  193. /* helpengine:  invoke the MS-Windows help engine */
  194. /* ==========                                     */
  195.  
  196. PASCAL helpengine (int f, int n)
  197. {
  198.     char    OldHelpFile [NFILEN];
  199.     char    HelpKey [NLINE];
  200.     BOOL    Result;
  201.  
  202.     strcpy (OldHelpFile, HelpEngineFile);
  203.     SetWorkingDir ();
  204.     if ((Result = FILENAMEREPLY (TEXT307, HelpEngineFile, NFILEN)) != TRUE) return Result;
  205.         /* "Help file: " */
  206.     if (HelpEngineFile[0] == '\0') {
  207.         strcpy (HelpEngineFile, OldHelpFile);
  208.         return FALSE;
  209.     }
  210.     else {
  211.         Result = mlreply (TEXT308, HelpKey, NLINE);
  212.     if ((Result != TRUE) && (Result != FALSE)) return Result;
  213.         /* "Help key: " */
  214.     if (HelpKey[0] == '\0') {
  215.         WinHelp (hFrameWnd, HelpEngineFile, HELP_INDEX, NULL);
  216.     }
  217.     else {
  218.         WinHelp (hFrameWnd, HelpEngineFile, HELP_KEY,
  219.                      (DWORD)(LPSTR)&HelpKey[0]);
  220.     }
  221.     }
  222.     return TRUE;
  223. } /* helpengine */
  224.  
  225. /* minimizescreen:  turn the current screen into an icon */
  226. /* ==============                                        */
  227.  
  228. PASCAL  minimizescreen (int f, int n)
  229. {
  230.     BOOL    nq;
  231.  
  232.     nq = notquiescent;
  233.     notquiescent = 0;
  234.     ShowWindow (first_screen->s_drvhandle, SW_MINIMIZE);
  235.     notquiescent = nq;
  236.     return TRUE;
  237. } /* minimizescreen */
  238.  
  239. /* ForceMessage:    do a SendMessage, forcing quiescent mode */
  240. /* ============                                              */
  241.  
  242. static pascal near  ForceMessage (HWND hWnd, WORD wMsg, WORD wParam, DWORD lParam)
  243. {
  244.     BOOL    nq;
  245.  
  246.     nq = notquiescent;
  247.     notquiescent = 0;
  248.     SendMessage (hWnd, wMsg, wParam, lParam);
  249.     notquiescent = nq;
  250. } /* ForceMessage */
  251.  
  252. /* maximizescreen:  maximize the current screen */
  253. /* ==============                               */
  254.  
  255. PASCAL  maximizescreen (int f, int n)
  256. {
  257.     ForceMessage (hMDIClientWnd, WM_MDIMAXIMIZE,
  258.                  first_screen->s_drvhandle, 0L);
  259.     return TRUE;
  260. } /* maximizescreen */
  261.  
  262. /* restorescreen:   restore the current screen from maximized/minimized state */
  263. /* =============                                                              */
  264.  
  265. PASCAL  restorescreen (int f, int n)
  266. {
  267.     ForceMessage (hMDIClientWnd, WM_MDIRESTORE,
  268.                  first_screen->s_drvhandle, 0L);
  269.     return TRUE;
  270. } /* restorescreen */
  271.  
  272. /* tilescreens: tile the non-iconized screens */
  273. /* ===========                                */
  274.  
  275. PASCAL  tilescreens (int f, int n)
  276. {
  277.     ForceMessage (hMDIClientWnd, WM_MDITILE, 0, 0L);
  278.     return TRUE;
  279. } /* tilescreens */
  280.  
  281. /* cascadescreens:  position the non-iconized screens in cascade */
  282. /* ==============                                                */
  283.  
  284. PASCAL  cascadescreens (int f, int n)
  285. {
  286.     ForceMessage (hMDIClientWnd, WM_MDICASCADE, 0, 0L);
  287.     return TRUE;
  288. } /* cascadescreens */
  289.  
  290. /* renamescreen:    change the current screen's name */
  291. /* ============                                      */
  292.  
  293. PASCAL  renamescreen (int f, int n)
  294. {
  295.     char    scr_name[NSTRING];  /* buffer to hold screen name */
  296.     int     result;
  297.  
  298.     /* get the new name of the screen */
  299.     if ((result = mlreply(TEXT335, scr_name, NSTRING)) != TRUE) {
  300.     /* "Change screen name to: " */
  301.     return result;
  302.     } 
  303.     if (lookup_screen(scr_name) != (SCREEN*)NULL) {
  304.     mlwrite (TEXT336);  /* "[Screen name already in use]" */
  305.     return FALSE;
  306.     }
  307.  
  308.     free (first_screen->s_screen_name);
  309.     first_screen->s_screen_name = copystr (scr_name);
  310.     SetWindowText ((HWND)first_screen->s_drvhandle, scr_name);
  311.     return TRUE;
  312. } /* renamescreen */
  313.